package user

import (
	"gitee.com/go-course/go11/vblog/common"
	"github.com/rs/xid"
	"golang.org/x/crypto/bcrypt"
)

func NewToken(username string) *Token {
	return &Token{
		Meta:     common.NewMeta(),
		Username: username,
		// 随机字符串, 没有任何含义
		AccessToken: xid.New().String(),
	}
}

type Token struct {
	*common.Meta
	// JWT
	AccessToken string `json:"token"`
	// 用户的名称
	Username string `json:"username"`
}

func (t *Token) String() string {
	return common.ToJSON(t)
}

func (t *Token) TableName() string {
	return "tokens"
}

func NewDefaultUser() *User {
	return NewUser(NewCreateUserRequest())
}

func NewUser(req *CreateUserRequest) *User {
	return &User{
		Meta:              common.NewMeta(),
		CreateUserRequest: req,
	}
}

type User struct {
	*common.Meta
	*CreateUserRequest
}

func (u *User) TableName() string {
	return "users"
}

func (u *User) String() string {
	return common.ToJSON(u)
}

// 将明文密码变成一个Hash
// 密码 ---> hash 是一一对应, 彩虹表： hash ---> pass
// 生成是很少这样方式的, 加盐
//
//		password  --->  bash
//		salt.password  -->  salt.hash
//	 password  + salt ---> salt.hash == salt/password
func (u *User) BuildHashedPassword() error {
	// h := sha1.New()
	// _, err := h.Write([]byte(u.Password))
	// if err != nil {
	// 	return err
	// }

	// hd := h.Sum(nil)

	// // base64 编码, []byte是二进制数据, 不一定可以转换成字符串
	// u.Password = base64.StdEncoding.EncodeToString(hd)

	// 专门用户Password hash的方法
	hp, err := bcrypt.GenerateFromPassword([]byte(u.Password), 10)
	if err != nil {
		return err
	}
	u.Password = string(hp)
	return nil
}

func (u *User) CheckPassord(planPassword string) error {
	return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(planPassword))
}

func NewCreateUserRequest() *CreateUserRequest {
	return &CreateUserRequest{}
}

type CreateUserRequest struct {
	Username string `json:"username" validate:"required"`
	Password string `json:"password" validate:"required"`
}

func (r *CreateUserRequest) Validate() error {
	return common.Validate(r)
}
